<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace Tool;

/**
 * Description of Tool
 *
 * @author jahem
 */
class Tool {

    /**
     * 数组相反
     * @param array $arr 数据内容
     * @return \Illuminate\Http\JsonResponse
     */
    public static function array_replace_key($arr){
        $ret = [];
        foreach ($arr as $key => $value) {
            $ret[$value] = $key;
        }
        return $ret;
    }
    /**
     * 公用AJAX响应 json
     * @param int $sta 状态码 ， 1 = 成功，0 = 失败
     * @param string $msg 信息内容
     * @param array $data 数据内容
     * @param array $other 其它字段
     * @param string $custom 定义数据键名
     * @return \Illuminate\Http\JsonResponse
     */
    public static function ajaxResponse($sta = 0, $msg = 'success', $data = [], array $other = [], $data_field = 'result') {
        $data = [
            'sta' => $sta,
            'msg' => $msg,
            $data_field => !!$data ? $data : new \stdClass(),
        ];
        if (count($other) > 0) {
            $data = array_merge($data, $other);
        }
        header('Content-type: application/json');
        return json_encode($data, JSON_UNESCAPED_UNICODE);
    }
    /**
     * 对emoji表情转义
     * @param string $str 需要转义的图标字符串
     * @return string
     */
    public static function emoji_encode($str) {
        $strEncode = '';
        $length = mb_strlen($str, 'utf-8');
        for ($i = 0; $i < $length; $i++) {
            $_tmpStr = mb_substr($str, $i, 1, 'utf-8');
            if (strlen($_tmpStr) >= 4) {
                $strEncode .= '[[EMOJI:' . rawurlencode($_tmpStr) . ']]';
            } else {
                $strEncode .= $_tmpStr;
            }
        }
        return $strEncode;
    }

    /**
     * 对emoji表情转反义
     * @param string $str 需要转反义的字符串
     * @return string
     */
    public static function emoji_decode($str) {
        $strDecode = preg_replace_callback('|\[\[EMOJI:(.*?)\]\]|', function($matches) {
            return rawurldecode($matches[1]);
        }, $str);
        return $strDecode;
    }

    /**
     * 去掉所有标点符号
     * @param string $str 需要去掉的字符串
     * @param boolean $all 是否去除，
     * @return string
     */
    public static function clear_sign($str, $all = false) {
        if ($all == false) {
            $char = "。、！？：；﹑•＂…‘’“”〝〞∕¦‖—　〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔！¡？¿﹖﹌﹏﹋＇´ˊˋ―﹫︳︴¯＿￣﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼（）";
        } else {
            $char = "，。、！？：；﹑•＂…‘’“”〝〞∕¦‖—　〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔！¡？¿﹖﹌﹏﹋＇´ˊˋ―﹫︳︴¯＿￣﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼（）";
        }
        $pattern = array(
            "/[[:punct:]]/i", //英文标点符号
            '/[' . $char . ']/u', //中文标点符号
            '/[ ]{2,}/'
        );
        // 去掉所有标点符号
        return preg_replace($pattern, ' ', str_replace(["/r/n", "/r", "/n"], " ", $str));
    }

    /**
     * 替换英文状态下不合法符号
     * @param string $str 不合法字符串
     * @return string
     */
    public static function toPreg_replace($str) {
        return preg_replace("/(\n)|(\s)|(\t)|(\')|(')|(，)/", ',', $str);
    }

    /**
     * 手机号码替换
     * @param string $phone 手机号码
     * @return string
     */
    public static function phone_str_ireplace($phone) {
        if (preg_match("/^1[345678]{1}\d{9}$/", $phone)) {
            $pattern = "/(\d{3})\d\d(\d{2})/";
            $replacement = "\$1****\$3";
            $phone = preg_replace($pattern, $replacement, $phone);
        }
        return $phone;
    }

    /**
     * 判断是否用了https证书
     * @return string
     */
    public static function is_https() {
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') {
            return 'https://';
        } elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
            return 'https://';
        } elseif (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off') {
            return 'https://';
        }
        return 'http://';
    }

    /**
     * 读取一个图像的第一个字节并检查其签名。linux下没有该函数，故替代函数
     * @param string $filename 图片完整磁盘地址
     * @return boolean
     */
    public static function exif_imagetype($filename) {
        if ((list($width, $height, $type, $attr) = getimagesize($filename) ) !== false) {
            return $type;
        }
        return false;
    }

    /**
     * 打印
     * @param all $content 内容
     */
    public static function p($content) {
        echo '<pre>';
        print_r($content);
        echo '</pre>';
    }

    /**
     * 计算文件夹下的文件数量
     * @param string $url 磁盘地址
     * @return int
     */
    public static function ShuLiang($url) {//造一个方法，给一个参数
        $sl = 0; //造一个变量，让他默认值为0;
        $arr = glob($url); //把该路径下所有的文件存到一个数组里面;
        foreach ($arr as $v) {//循环便利一下，吧数组$arr赋给$v;
            if (is_file($v)) {//先用个if判断一下这个文件夹下的文件是不是文件，有可能是文件夹;
                $sl++; //如果是文件，数量加一;
            } else {
                $sl += ShuLiang($v . "/*"); //如果是文件夹，那么再调用函数本身获取此文件夹下文件的数量，这种方法称为递归;
            }
        }
        return $sl; //当这个方法走完后，返回一个值$sl,这个值就是该路径下所有的文件数量;
    }

    /**
     * 设备获取
     * @return array
     */
    public static function getAgentInfo() {
        $agent = $_SERVER['HTTP_USER_AGENT'] ?? '';
        $brower = array(
            'MSIE' => '微软MSIE内核',
            'Firefox' => '火狐Firefox内核',
            'MicroMessenger/' => '微信MicroMessenger内核',
            'QQ/' => '腾讯QQ内核',
            'UCBrowser' => 'UC浏览器内核',
            'QQBrowser' => 'QQ浏览器内核',
            'Edge' => '微软Edge内核',
            'Chrome' => '谷歌Chrome内核',
            'Opera' => '欧朋Opera内核',
            'OPR' => '欧朋OPR内核',
            'Safari' => '苹果Safari内核',
            'Trident/' => '浏览器Trident内核'
        );
        $system = array(
            'Windows Phone' => 'Windows Phone',
            'Windows' => 'Windows',
            'Android' => 'Android',
            'iPhone' => 'ios',
            'iPad' => 'iPadios'
        );
        $browser_num = '未知'; //未知  
        $system_num = '未知'; //未知  
        foreach ($brower as $bro => $val) {
            if (strstr($agent, $bro) !== false) {
                $browser_num = $val;
                break;
            }
        }
        foreach ($system as $sys => $val) {
            if (strstr($agent, $sys) !== false) {
                $system_num = $val;
                break;
            }
        }
        $browser_num = empty($browser_num) ? '未知' : $browser_num;
        $system_num = empty($system_num) ? '未知' : $system_num;
        return array('system' => $system_num, 'brower' => $browser_num);
    }

    /**
     * 百度短信
     * @param string $phone 手机
     * @param string $content 内容
     * @param string $apikey 百度apikey
     * @return object
     */
    public static function baidu_Msm($phone, $content, $apikey) {
        $ch = curl_init();
        $url = "http://apis.baidu.com/kingtto_media/106sms/106sms?mobile={$phone}&content={$content}";
        $header = array(
            "apikey:{$apikey}",
        );
        // 添加apikey到header
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 执行HTTP请求
        curl_setopt($ch, CURLOPT_URL, $url);
        $res = curl_exec($ch);
        $json = json_decode($res);
        return $json;
    }

    /**
     * 云片短信
     * @param string $phone 手机
     * @param string $content 内容
     * @param string $apikey 云片apikey
     * @return object
     */
    public static function yunpian_Msm($phone, $content, $apikey) {
        $data = array('text' => $content, 'apikey' => $apikey, 'mobile' => $phone);
        $ch = curl_init();
        /* 设置验证方式 */
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept:text/plain;charset=utf-8',
            'Content-Type:application/x-www-form-urlencoded', 'charset=utf-8'));
        /* 设置返回结果为流 */
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        /* 设置超时时间 */
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        /* 设置通信方式 */
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_URL, 'https://sms.yunpian.com/v2/sms/single_send.json');
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        $result = curl_exec($ch);
        $json = json_decode($result);
        return $json;
    }

    /**
     * 获取ip
     * @return string
     */
    public static function getIP() {
        if (getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('HTTP_X_FORWARDED')) {
            $ip = getenv('HTTP_X_FORWARDED');
        } elseif (getenv('HTTP_FORWARDED_FOR')) {
            $ip = getenv('HTTP_FORWARDED_FOR');
        } elseif (getenv('HTTP_FORWARDED')) {
            $ip = getenv('HTTP_FORWARDED');
        } else {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $ip;
    }

    /**
     * 百度获取ip所属区域
     * @param string $IP ip地址
     * @param string $apikey 百度apikey
     * @return object
     */
    public static function baiud_Area($IP, $apikey) {
        $url = 'http://api.map.baidu.com/location/ip?ip=' . $IP . '&ak=' . $apikey;
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        $json = json_decode($res);
        return $json;
    }

    /**
     * 判断是否手机设备
     * @return boolean
     */
    public static function isMobile() {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
            return true;
        }
        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset($_SERVER['HTTP_VIA'])) {
            // 找不到为flase,否则为true
            return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
        }
        // 协议法，因为有可能不准确，放到最后判断
        if (isset($_SERVER['HTTP_ACCEPT'])) {
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 数组转json
     * @param array|object 需要转换的数组或对象
     * @return string
     */
    public static function toJson($arr) {
        if (is_string($arr)) {
            return '';
        } else {
            header('Content-type: application/json');
            return json_encode($arr, JSON_UNESCAPED_UNICODE);
        }
    }

    /**
     * json转数组
     * @param string $json 需要转换的json对象
     * @return string
     */
    public static function toArr($json) {
        if (is_string($json)) {
            return json_decode($json, true);
        } else {
            return '';
        }
    }

    /**
     * 生成token
     * @return string
     */
    public static function settoken() {
        $str = md5(uniqid(md5(microtime(true)), true));  //生成一个不会重复的字符串
        $str = sha1($str);  //加密
        return $str;
    }

    /**
     * 随机生成字符串
     * @param int $length 生成长度
     * @return string
     */
    public static function createRandomStr($length) {
        $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; //62个字符 
        $strlen = 62;
        while ($length > $strlen) {
            $str .= $str;
            $strlen += 62;
        }
        $str = str_shuffle($str);
        return substr($str, 0, $length);
    }

    /**
     * 指定插入位置前的字符串
     * @param string $str 原字符串
     * @param string $i 查找插入的字符串
     * @param string $substr 需要插入的字符串
     * @return string
     */
    public static function insertToStr($str, $i, $substr) {
        //指定插入位置前的字符串
        $startstr = "";
        for ($j = 0; $j < $i; $j++) {
            $startstr .= $str[$j];
        }
        //指定插入位置后的字符串
        $laststr = "";
        for ($j = $i; $j < strlen($str); $j++) {
            $laststr .= $str[$j];
        }
        //将插入位置前，要插入的，插入位置后三个字符串拼接起来
        $str = $startstr . $substr . $laststr;
        //返回结果
        return $str;
    }

    /**
     * post curl 提交
     * @param string $url 提交地址
     * @param all $post_date 提交数据
     * @return all 
     */
    public static function httpPost($url, $post_date) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_POST, true); // enable posting
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_date); // post
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // if any redirection after upload
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    /**
     * get curl 提交
     * @param string $url 提交地址
     * @return all
     */
    public static function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    /**
     * request curl 提交
     * @param string $url 提交地址
     * @param all $data 提交数据
     * @return all
     */
    function https_request($url, $data = null) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $cutput = curl_exec($curl);
        curl_close($curl);
        return $cutput;
    }

    /**
     * 两个一维数组对比差集
     * @param array $array1 数组1
     * @param array $array2 数组2
     * @return array
     */
    public static function array_diff_assoc2_deep($array1, $array2) {
        $ret = array();
        foreach ($array1 as $k => $v) {
            if (!isset($array2[$k]))
                $ret[$k] = $v;
            else if (is_array($v) && is_array($array2[$k]))
                $ret[$k] = array_diff_assoc2_deep($v, $array2[$k]);
            else if ($v != $array2[$k])
                $ret[$k] = $v;
            else {
                unset($array1[$k]);
            }
        }
        return $ret;
    }

    /**
     * 两个2维数组对比差集
     * @param array $arr1 数组1
     * @param array $arr2 数组2
     * @return array
     */
    public static function get_diff_array_by_filter($arr1, $arr2) {
        try {
            return array_filter($arr1, function($v) use ($arr2) {
                return !in_array($v, $arr2);
            });
        } catch (\Exception $exception) {
            return $arr1;
        }
    }

}
